using System.Collections.Generic;
using System.Text;

namespace OracleInternal.SqlAndPlsqlParser.LocalParsing
{
	internal class OracleLpSelectTermSpecific : OracleLpSelectTerm
	{
		protected OracleLpExpression m_vExpression;

		protected OracleLpName m_vAlias;

		protected int m_vBindRefStart = -1;

		protected int m_vBindRefEnd = -1;

		public OracleLpExpression Expression
		{
			get
			{
				return m_vExpression;
			}
			set
			{
				m_vExpression = value;
				if (m_vExpression != null)
				{
					m_vExpression.Parent = this;
				}
			}
		}

		public OracleLpTextFragment ExpressionText
		{
			get
			{
				if (m_vExpression != null)
				{
					return m_vExpression.Text;
				}
				return null;
			}
		}

		public OracleLpName Alias
		{
			get
			{
				return m_vAlias;
			}
			set
			{
				m_vAlias = value;
			}
		}

		public int BindRefStart
		{
			get
			{
				return m_vBindRefStart;
			}
			set
			{
				m_vBindRefStart = value;
			}
		}

		public int BindRefEnd
		{
			get
			{
				return m_vBindRefEnd;
			}
			set
			{
				m_vBindRefEnd = value;
			}
		}

		public OracleLpSelectTermSpecific(OracleLpSelectClause sc)
			: base(sc)
		{
			m_vType = OracleLpSelectTermType.SPECIFIC;
		}

		public override void Resolve()
		{
			OracleLpQueryBlock oracleLpQueryBlock = m_vParent.Parent as OracleLpQueryBlock;
			if (m_vColumnDescriptors == null)
			{
				m_vColumnDescriptors = new List<OracleLpColumnDescriptor>();
			}
			OracleLpColumnDescriptor oracleLpColumnDescriptor = null;
			if (m_vExpression == null)
			{
				oracleLpColumnDescriptor = new OracleLpColumnDescriptor();
				oracleLpColumnDescriptor.BaseColumnName = new OracleLpName(ExpressionText.Fragment);
				oracleLpColumnDescriptor.ColumnName = oracleLpColumnDescriptor.BaseColumnName;
				oracleLpColumnDescriptor.ColumnType = OracleLpColumnType.Expression;
			}
			else
			{
				switch (m_vExpression.ExpressionType)
				{
				case OracleLpExpressionType.SIMPLE_EXPRESSION:
					switch (((OracleLpSimpleExpression)m_vExpression).SimpleExpressionType)
					{
					case OracleLpSimpleExpressionType.COLUMN:
					{
						OracleLpColumn column = ((OracleLpColumnExpression)m_vExpression).Column;
						oracleLpColumnDescriptor = oracleLpQueryBlock.FromClause.FindColumn(column.SchemaName, column.ParentObjectName, column.Name);
						break;
					}
					case OracleLpSimpleExpressionType.CONSTANT:
					{
						oracleLpColumnDescriptor = new OracleLpColumnDescriptor();
						object expressionValue = ((OracleLpConstantExpression)m_vExpression).ExpressionValue;
						oracleLpColumnDescriptor.BaseColumnName = new OracleLpName(expressionValue.ToString());
						oracleLpColumnDescriptor.ColumnName = oracleLpColumnDescriptor.BaseColumnName;
						oracleLpColumnDescriptor.ColumnType = OracleLpColumnType.Constant;
						break;
					}
					case OracleLpSimpleExpressionType.PSEUDOCOLUMN:
					{
						oracleLpColumnDescriptor = new OracleLpColumnDescriptor();
						oracleLpColumnDescriptor.ColumnType = OracleLpColumnType.PseudoColumn;
						OracleLpPseudoColumnExpression oracleLpPseudoColumnExpression = (OracleLpPseudoColumnExpression)m_vExpression;
						switch (oracleLpPseudoColumnExpression.PseudoColumnExpressionType)
						{
						case OracleLpPseudoColumnExpressionType.ROWID:
							oracleLpColumnDescriptor.BaseColumnName = new OracleLpName("ROWID");
							oracleLpColumnDescriptor.ColumnName = oracleLpColumnDescriptor.BaseColumnName;
							oracleLpColumnDescriptor.PseudoColumnType = OracleLpPseudoColumnType.ROWID;
							break;
						case OracleLpPseudoColumnExpressionType.ROWNUM:
							oracleLpColumnDescriptor.BaseColumnName = new OracleLpName("ROWNUM");
							oracleLpColumnDescriptor.ColumnName = oracleLpColumnDescriptor.BaseColumnName;
							oracleLpColumnDescriptor.PseudoColumnType = OracleLpPseudoColumnType.ROWNUM;
							break;
						case OracleLpPseudoColumnExpressionType.CONNECT_BY_ROOT:
						{
							OracleLpExpression vExpression = m_vExpression;
							m_vExpression = ((OracleLpPseudoColumnExpression)m_vExpression).Expression;
							Resolve();
							m_vExpression = vExpression;
							oracleLpColumnDescriptor = m_vColumnDescriptors[m_vColumnDescriptors.Count - 1];
							oracleLpColumnDescriptor.ColumnType = OracleLpColumnType.PseudoColumn;
							oracleLpColumnDescriptor.PseudoColumnType = OracleLpPseudoColumnType.CONNECT_BY_ROOT;
							oracleLpColumnDescriptor = null;
							break;
						}
						}
						OracleLpQteNamedObject oracleLpQteNamedObject = oracleLpQueryBlock.FromClause.FindNamedObject(oracleLpPseudoColumnExpression.SchemaName, oracleLpPseudoColumnExpression.ParentObjectName);
						if (oracleLpQteNamedObject != null)
						{
							oracleLpColumnDescriptor.BaseTableName = oracleLpQteNamedObject.ObjectName;
							oracleLpColumnDescriptor.BaseSchemaName = oracleLpQteNamedObject.SchemaName;
						}
						break;
					}
					}
					break;
				case OracleLpExpressionType.SCALAR_SUBQUERY_EXPRESSION:
					oracleLpColumnDescriptor = new OracleLpColumnDescriptor((m_vExpression as OracleLpScalarSubqueryExpression).Subquery.ColumnDescriptors[0]);
					m_vBindRefStart = (m_vBindRefEnd = -1);
					oracleLpColumnDescriptor.ColumnName = new OracleLpName(m_vExpression.Text.Fragment);
					oracleLpColumnDescriptor.IsShowing = true;
					break;
				default:
					oracleLpColumnDescriptor = new OracleLpColumnDescriptor();
					oracleLpColumnDescriptor.BaseColumnName = new OracleLpName(m_vExpression.ToString());
					oracleLpColumnDescriptor.ColumnName = oracleLpColumnDescriptor.BaseColumnName;
					oracleLpColumnDescriptor.ColumnType = OracleLpColumnType.Expression;
					break;
				}
			}
			if (oracleLpColumnDescriptor == null)
			{
				return;
			}
			if (m_vAlias != null)
			{
				oracleLpColumnDescriptor.ColumnName = m_vAlias;
			}
			if (m_vBindRefEnd != m_vBindRefStart)
			{
				OracleLpSelectStatement oracleLpSelectStatement = base.TopElement as OracleLpSelectStatement;
				for (int i = m_vBindRefStart; i < m_vBindRefEnd; i++)
				{
					oracleLpColumnDescriptor.AddBindReference(oracleLpSelectStatement.BindParameters[i]);
				}
			}
			m_vColumnDescriptors.Add(oracleLpColumnDescriptor);
		}

		internal override void ToString(StringBuilder sb)
		{
			string depthIndent = base.DepthIndent;
			sb.Append(depthIndent);
			sb.Append("Alias: ");
			sb.Append((m_vAlias == null) ? "none" : (m_vAlias.DbName ?? "none"));
			sb.Append("  Expression: ");
			if (m_vExpression != null)
			{
				m_vExpression.ToString(sb);
			}
			else
			{
				sb.Append(m_vExpression.Text.Fragment);
			}
			sb.Append('\n');
		}
	}
}
